#include "chess_pieces.h"

chess_pieces::chess_pieces(int camp, int chesstype, Position pos, QString filepath)
{
    this->camp = camp;
    this->chess_type = chesstype;
    this->pos = pos;
    this->filepath = filepath;
}

Position chess_pieces::getPosition()
{
    return pos;
}

QString chess_pieces::getfilepath()
{
    return filepath;
}

void chess_pieces::setPosition(const Position &pos)
{
    this->pos = pos;
}

int chess_pieces::getChessType()
{
    return chess_type;
}

ChessInfo chess_pieces::getChessInfo()
{
    ChessInfo info = {.camp = camp, .chess_type = chess_type, .pos = pos};
    return info;
}

bool chess_pieces::IsSelfChess(int camp, QPoint target_pos, QVector<chess_pieces> &red, QVector<chess_pieces> &black)
{
    if (camp == RED)
    {
        for (int i = 0; i < red.length(); i++)
        {
            if (red[i].getPosition().x == target_pos.x() && red[i].getPosition().y == target_pos.y())
            {
                return true;
            }
        }
    }
    else if (camp == BLACK)
    {
        for (int i = 0; i < black.length(); i++)
        {
            if (black[i].getPosition().x == target_pos.x() && black[i].getPosition().y == target_pos.y())
            {
                return true;
            }
        }
    }
    return false;
}

bool chess_pieces::Redarms_Cache(int Camp, QPoint target_pos, QVector<chess_pieces> &red, QVector<chess_pieces> &black)
{
    Position pos = this->pos;
    //兵
    //检测目标是不是自己人
    if (IsSelfChess(Camp, target_pos, red, black))
    {
        //目标是自己人 不能走
        return false;
    }

    if (Camp == BLACK)
    {
        //黑色
        target_pos.setY(Boundary_max_y - target_pos.y());
        pos.y = Boundary_max_y - pos.y;
    }
    if (target_pos.y() <= Mid_red)
    {
        //没有过河
        if ((unsigned int)target_pos.y() == pos.y + 1 && (unsigned int)target_pos.x() == pos.x)
        {
            //向前走一步
            //有效
            return true;
        }
        return false;
    }
    else
    {
        //已经过河
        if ((unsigned int)target_pos.y() == pos.y + 1 && (unsigned int)target_pos.x() == pos.x)
        {
            //向前走一步
            return true;
        }
        if ((unsigned int)target_pos.y() == pos.y && ((unsigned int)target_pos.x() == pos.x - 1 || (unsigned int)target_pos.x() == pos.x + 1))
        {
            //向左或右走一步
            return true;
        }
        return false;
    }
}

bool chess_pieces::Gun_Cache(int Camp, QPoint target_pos, QVector<chess_pieces> &red, QVector<chess_pieces> &black)
{
    Position pos = this->pos;

    if ((unsigned int)target_pos.y() == pos.y || (unsigned int)target_pos.x() == pos.x)
    {
        //直走
        //检测目标是不是自己人
        if (IsSelfChess(Camp, target_pos, red, black))
        {
            //目标是自己人 不能走
            return false;
        }

        if ((unsigned int)target_pos.x() == pos.x)
        {
            //竖着 走
            int min_y = (unsigned int)target_pos.y() > pos.y ? pos.y : target_pos.y();
            int max_y = (unsigned int)target_pos.y() > pos.y ? target_pos.y() : pos.y;
            int HaveMidNum = 0;
            for (int i = 0; i < red.length(); i++)
            {
                if (pos.x == red[i].getPosition().x && red[i].getPosition().y > (unsigned int)min_y && red[i].getPosition().y < (unsigned int)max_y)
                {
                    //中间有红方的人
                    HaveMidNum++;
                }
            }
            for (int i = 0; i < black.length(); i++)
            {
                if (pos.x == black[i].getPosition().x && black[i].getPosition().y > (unsigned int)min_y && black[i].getPosition().y < (unsigned int)max_y)
                {
                    //中间有黑方的人
                    HaveMidNum++;
                }
            }

            if (HaveMidNum == 0 || HaveMidNum == 1)
            {
                //中间只有一个人 或则没有人
                if (HaveMidNum == 0)
                {
                    //检测目标是不是敌人
                    if (camp == BLACK)
                    {
                        for (int i = 0; i < red.length(); i++)
                        {
                            if (red[i].getPosition().x == target_pos.x() && red[i].getPosition().y == target_pos.y())
                            {
                                //是敌人
                                return false;
                            }
                        }
                    }
                    else if (camp == RED)
                    {
                        for (int i = 0; i < black.length(); i++)
                        {
                            if (black[i].getPosition().x == target_pos.x() && black[i].getPosition().y == target_pos.y())
                            {
                                //是敌人
                                return false;
                            }
                        }
                    }
                    //没有人
                    return true;
                }
                else
                {
                    //中间只有一个人,判断目标位置是不是敌人，是则可以杀掉，不是则不能走
                    if (Camp == RED)
                    {
                        int i = 0;
                        for (i = 0; i < black.length(); i++)
                        {
                            if ((unsigned int)target_pos.x() == black[i].getPosition().x && (unsigned int)target_pos.y() == black[i].getPosition().y)
                            {
                                //目标位置是敌人
                                return true;
                            }
                        }
                        //目标位置没有敌人
                        return false;
                    }
                    else if (Camp == BLACK)
                    {
                        int i = 0;
                        for (i = 0; i < red.length(); i++)
                        {
                            if ((unsigned int)target_pos.x() == red[i].getPosition().x && (unsigned int)target_pos.y() == red[i].getPosition().y)
                            {
                                //目标位置是敌人
                                return true;
                            }
                        }
                        //目标位置没有敌人
                        return false;
                    }
                }
            }
            //多个人
            return false;
        }

        //横走
        if ((unsigned int)target_pos.y() == pos.y)
        {
            int min_x = (unsigned int)target_pos.x() > pos.x ? pos.x : target_pos.x();
            int max_x = (unsigned int)target_pos.x() > pos.x ? target_pos.x() : pos.x;
            int HaveMidNum = 0;
            for (int i = 0; i < red.length(); i++)
            {
                if (pos.y == red[i].getPosition().y && red[i].getPosition().x > (unsigned int)min_x && red[i].getPosition().x < (unsigned int)max_x)
                {
                    //中间有红方的人
                    HaveMidNum++;
                }
            }
            for (int i = 0; i < black.length(); i++)
            {
                if (pos.y == black[i].getPosition().y && black[i].getPosition().x > (unsigned int)min_x && black[i].getPosition().x < (unsigned int)max_x)
                {
                    //中间有黑方的人
                    HaveMidNum++;
                }
            }

            if (HaveMidNum == 0 || HaveMidNum == 1)
            {
                //中间只有一个人 或则没有人
                if (HaveMidNum == 0)
                {
                    //检测目标是不是敌人
                    if (camp == BLACK)
                    {
                        for (int i = 0; i < red.length(); i++)
                        {
                            if (red[i].getPosition().x == target_pos.x() && red[i].getPosition().y == target_pos.y())
                            {
                                //是敌人
                                return false;
                            }
                        }
                    }
                    else if (camp == RED)
                    {
                        for (int i = 0; i < black.length(); i++)
                        {
                            if (black[i].getPosition().x == target_pos.x() && black[i].getPosition().y == target_pos.y())
                            {
                                //是敌人
                                return false;
                            }
                        }
                    }
                    //空的
                    return true;
                }
                else
                {
                    //中间只有一个人,判断目标位置是不是敌人，是则可以杀掉，不是则不能走
                    if (Camp == RED)
                    {
                        int i = 0;
                        for (i = 0; i < black.length(); i++)
                        {
                            if ((unsigned int)target_pos.x() == black[i].getPosition().x && (unsigned int)target_pos.y() == black[i].getPosition().y)
                            {
                                //目标位置是敌人
                                return true;
                            }
                        }
                        //目标位置没有敌人
                        return false;
                    }
                    else if (Camp == BLACK)
                    {
                        int i = 0;
                        for (i = 0; i < red.length(); i++)
                        {
                            if ((unsigned int)target_pos.x() == red[i].getPosition().x && (unsigned int)target_pos.y() == red[i].getPosition().y)
                            {
                                //目标位置是敌人
                                return true;
                            }
                        }
                        //目标位置没有敌人
                        return false;
                    }
                }
            }
            //多个人
            return false;
        }
    }
    return false;
}

bool chess_pieces::Will_Cache(int Camp, QPoint target_pos, QVector<chess_pieces> &red, QVector<chess_pieces> &black)
{
    //检测目标是不是自己人
    if (IsSelfChess(Camp, target_pos, red, black))
    {
        //目标是自己人 不能走
        return false;
    }

    //飞将，直接吃掉对方将军
    if (Camp == BLACK)
    {
        for (int i = 0; i < red.length(); i++)
        {
            if (red[i].getChessType() == Will && red[i].getPosition().x == (unsigned int)target_pos.x() && red[i].getPosition().y == (unsigned int)target_pos.y())
            {
                return true;
            }
        }
    }
    else if (Camp == RED)
    {
        for (int i = 0; i < black.length(); i++)
        {
            if (black[i].getChessType() == Will && black[i].getPosition().x == (unsigned int)target_pos.x() && black[i].getPosition().y == (unsigned int)target_pos.y())
            {
                return true;
            }
        }
    }

    if (Camp == RED)
    {
        if (target_pos.x() >= Will_min_red_x && target_pos.x() <= Will_max_red_x &&
            target_pos.y() >= Will_min_red_y && target_pos.y() <= Will_max_red_y)
        {
            //将在框中活动 且目标不是自己人
            //保证一次直走一步
            if (qAbs(qAbs(target_pos.x() - (int)pos.x) + qAbs(target_pos.y() - (int)pos.y)) == 1)
            {
                //保证只有一步
                return true;
            }
            qDebug() << "走了多步" << qAbs(target_pos.x() - pos.x) + qAbs(target_pos.y() - pos.y);
            return false;
        }
    }
    else if (Camp == BLACK)
    {
        // 仕在框中走
        if (target_pos.x() >= Will_min_black_x && target_pos.x() <= Will_max_black_x &&
            target_pos.y() >= Will_min_black_y && target_pos.y() <= Will_max_black_y)
        {
            //将在框中活动 且目标不是自己人
            //保证一次直走一步
            if (qAbs(target_pos.x() - (int)pos.x) + qAbs(target_pos.y() - (int)pos.y) == 1)
            {
                //保证只有一步
                return true;
            }
            qDebug() << "走了多步" << qAbs(target_pos.x() - pos.x) + qAbs(target_pos.y() - pos.y);
            return false;
        }
    }
    return false;
}

// 仕
bool chess_pieces::Bachelor_Cache(int Camp, QPoint target_pos, QVector<chess_pieces> &red, QVector<chess_pieces> &black)
{
    Position pos = this->pos;
    //检测目标是不是自己人
    if (IsSelfChess(Camp, target_pos, red, black))
    {
        //目标是自己人 不能走
        return false;
    }

    if (Camp == RED)
    {
        // 仕在框中走
        if (target_pos.x() >= Will_min_red_x && target_pos.x() <= Will_max_red_x &&
            target_pos.y() >= Will_min_red_y && target_pos.y() <= Will_max_red_y)
        {
            //仕在框中活动 且目标不是自己人
            //保证斜着 走一步
            // x^2*y^2=二
            int value = 10 * sqrt((target_pos.x() - pos.x) * (target_pos.x() - pos.x) + (target_pos.y() - pos.y) * (target_pos.y() - pos.y));
            if (value == (int)(sqrt(2) * 10))
            {
                //保证斜着 走一步
                return true;
            }
            return false;
        }
        // 不在框中走
        return false;
    }
    else if (Camp == BLACK)
    {
        // 仕在框中走
        if (target_pos.x() >= Will_min_black_x && target_pos.x() <= Will_max_black_x &&
            target_pos.y() >= Will_min_black_y && target_pos.y() <= Will_max_black_y)
        {
            //仕在框中活动 且目标不是自己人
            //保证斜着 走一步
            // x^2*y^2=二
            int value = 10 * sqrt((target_pos.x() - pos.x) * (target_pos.x() - pos.x) + (target_pos.y() - pos.y) * (target_pos.y() - pos.y));
            if (value == (int)(sqrt(2) * 10))
            {
                //保证斜着 走一步
                return true;
            }
            return false;
        }
        // 不在框中走
        return false;
    }
    return false;
}

// 判断象走子
bool chess_pieces::Elephant_Cache(int Camp, QPoint target_pos, QVector<chess_pieces> &red, QVector<chess_pieces> &black)
{

    //检测目标是不是自己人
    if (IsSelfChess(Camp, target_pos, red, black))
    {
        //目标是自己人 不能走
        return false;
    }

    if (Camp == RED)
    {
        if (target_pos.y() > Mid_red)
        {
            // 过河
            qDebug() << "红 不能过河";
            return false;
        }
    }
    else if (Camp == BLACK)
    {
        if (target_pos.y() < Mid_black)
        {
            // 过河
            qDebug() << "黑 不能过河";
            return false;
        }
    }
    // 没有过河
    // 判断是否在走位上
    if ((((unsigned int)target_pos.y() == pos.y + 2) || ((unsigned int)target_pos.y() == pos.y - 2)) && (((unsigned int)target_pos.x() == pos.x + 2) || ((unsigned int)target_pos.x() == pos.x - 2)))
    {
        bool IsFeet = false;
        // 获取象脚
        Position elephant_feet = {.x = (target_pos.x() + pos.x) / 2, .y = (target_pos.y() + pos.y) / 2};
        // 判断是否是跘象脚
        for (int i = 0; i < red.length(); i++)
        {
            if (red[i].getPosition().x == elephant_feet.x && red[i].getPosition().y == elephant_feet.y)
            {
                IsFeet = true;
                break;
            }
        }
        for (int i = 0; i < black.length(); i++)
        {
            if (black[i].getPosition().x == elephant_feet.x && black[i].getPosition().y == elephant_feet.y)
            {
                IsFeet = true;
                break;
            }
        }
        if (!IsFeet)
        {
            return true;
        }
        qDebug() << "跘象脚了";
        // 跘象脚了
        return false;
    }
    return false;
}

bool chess_pieces::car_Cache(int Camp, QPoint target_pos, QVector<chess_pieces> &red, QVector<chess_pieces> &black)
{
    //判断是否是直线
    if (this->pos.x != target_pos.x() && this->pos.y != target_pos.y())
        return false;
    //判断目标点是否是己方
    if (IsSelfChess(Camp, target_pos, red, black))
        return false;
    //不是己方的点
    int min = -1; //存放最小的坐表
    int max = -1;
    //沿X轴
    if (target_pos.y() == this->pos.y)
    {
        if (target_pos.x() > this->pos.x)
        {
            min = this->pos.x;
            max = target_pos.x();
        }
        else if (target_pos.x() < this->pos.x)
        {
            min = target_pos.x();
            max = this->pos.x;
        }
        for (int i = min + 1; i < max; i++)
        {
            for (int j = 0; j < red.length(); j++)
            {
                if (red[j].pos.x == i && red[j].pos.y == target_pos.y())
                    return false;
            }
            for (int j = 0; j < black.length(); j++)
            {
                if (black[j].pos.x == i && black[j].pos.y == target_pos.y())
                    return false;
            }
        }
    }
    //沿y轴
    if (target_pos.x() == this->pos.x)
    {
        if (target_pos.y() > this->pos.y)
        {
            min = this->pos.y;
            max = target_pos.y();
        }
        else if (target_pos.y() < this->pos.y)
        {
            min = target_pos.y();
            max = this->pos.y;
        }
        for (int i = min + 1; i < max; i++)
        {
            for (int j = 0; j < red.length(); j++)
            {
                if (red[j].pos.y == i && red[j].pos.x == target_pos.x())
                    return false;
            }
            for (int j = 0; j < black.length(); j++)
            {
                if (black[j].pos.y == i && black[j].pos.x == target_pos.x())
                    return false;
            }
        }
    }
    return true;
}

bool chess_pieces::houre_Cache(int Camp, QPoint target_pos, QVector<chess_pieces> &red, QVector<chess_pieces> &black)
{
    //先判断是否符合走棋规则,不是返回true
    if (!((1 == qAbs(target_pos.x() - (int)this->pos.x) && 2 == qAbs(target_pos.y() - (int)this->pos.y)) || (2 == qAbs(target_pos.x() - (int)this->pos.x) && 1 == qAbs(target_pos.y() - (int)this->pos.y))))
    {
        qDebug() << "不是日字";
        return false;
    }
    //符合走棋规则，判断目标点是否时地方棋子是继续判断，否直接返回flase
    if (IsSelfChess(Camp, target_pos, red, black))
    {
        qDebug() << "目标位置是自己人";
        return false;
    }
    //对方棋子，判断是否蹩脚
    //如果第二次的点的y坐标减第一次点的y坐标为2
    if (2 == target_pos.y() - this->pos.y)
    {
        QPoint trippos = QPoint(this->pos.x, this->pos.y + 1);
        for (int i = 0; i < black.length(); i++)
        {
            if ((black[i].pos.x == (unsigned int)trippos.x()) && (black[i].pos.y == (unsigned int)trippos.y()))
            {
                qDebug() << "向下 跘马脚了";
                return false;
            }
        }
        for (int i = 0; i < red.length(); i++)
        {
            if ((red[i].pos.x == (unsigned int)trippos.x()) && (red[i].pos.y == (unsigned int)trippos.y()))
            {
                qDebug() << "向下 跘马脚了";
                return false;
            }
        }
    }
    //如果第二次的点的y坐标减第一次点的y坐标为-2
    if (-2 == (int)((unsigned int)target_pos.y() - this->pos.y))
    {
        QPoint trippos = QPoint(this->pos.x, this->pos.y - 1);
        for (int i = 0; i < black.length(); i++)
        {
            if ((black[i].pos.x == (unsigned int)trippos.x()) && (black[i].pos.y == (unsigned int)trippos.y()))
            {
                qDebug() << "向上 跘马脚了";
                return false;
            }
        }
        for (int i = 0; i < red.length(); i++)
        {
            if ((red[i].pos.x == (unsigned int)trippos.x()) && (red[i].pos.y == (unsigned int)trippos.y()))
            {
                qDebug() << "向上 跘马脚了";
                return false;
            }
        }
    }
    //如果第二次的点的x坐标减第一次点的x坐标为2
    if (2 == target_pos.x() - this->pos.x)
    {
        QPoint trippos = QPoint(this->pos.x + 1, this->pos.y);
        for (int i = 0; i < black.length(); i++)
        {
            if ((black[i].pos.x == (unsigned int)trippos.x()) && (black[i].pos.y == (unsigned int)trippos.y()))
            {
                qDebug() << "向右 跘马脚了";
                return false;
            }
        }
        for (int i = 0; i < red.length(); i++)
        {
            if ((red[i].pos.x == (unsigned int)trippos.x()) && (red[i].pos.y == (unsigned int)trippos.y()))
            {
                qDebug() << "向右 跘马脚了";
                return false;
            }
        }
    }
    //如果第二次的点的x坐标减第一次点的x坐标为-2
    if (-2 == (int)((unsigned int)target_pos.x() - this->pos.x))
    {
        QPoint trippos = QPoint(this->pos.x - 1, this->pos.y);
        for (int i = 0; i < black.length(); i++)
        {
            if ((black[i].pos.x == trippos.x()) && (black[i].pos.y == trippos.y()))
            {
                qDebug() << "向左 跘马脚了";
                return false;
            }
        }
        for (int i = 0; i < red.length(); i++)
        {
            if ((red[i].pos.x == (unsigned int)trippos.x()) && (red[i].pos.y == (unsigned int)trippos.y()))
            {
                qDebug() << "向左 跘马脚了";
                return false;
            }
        }
    }
    return true;
}

bool chess_pieces::IsActionEfficacious(int Camp, QPoint target_pos, QVector<chess_pieces> &red, QVector<chess_pieces> black)
{
    switch (chess_type)
    {
    case CarLeft:
    case CarRight:
        // 车的算法
        return car_Cache(Camp, target_pos, red, black);

    case HorseLeft:
    case HorseRight:
        // 马的算法
        return houre_Cache(Camp, target_pos, red, black);

    case ElephantLeft:
    case ElephantRight:
        // 象的算法
        return Elephant_Cache(Camp, target_pos, red, black);

    case BachelorLeft:
    case BachelorRight:
        // 仕的算法
        return Bachelor_Cache(Camp, target_pos, red, black);

    case GunLeft:
    case GunRight:
        // 炮的算法
        return Gun_Cache(Camp, target_pos, red, black);

    case Will:
        // 将的算法
        return Will_Cache(Camp, target_pos, red, black);

    case Redarms1:
    case Redarms2:
    case Redarms3:
    case Redarms4:
    case Redarms5:
        // 兵的算法
        return Redarms_Cache(Camp, target_pos, red, black);

    default:
        break;
    }
    return false;
}
